package android.slc.appbase.ui.vd;

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.Lifecycle;
import androidx.viewpager2.adapter.FragmentStateAdapter;
import androidx.viewpager2.widget.ViewPager2;

import com.blankj.utilcode.util.ArrayUtils;
import com.blankj.utilcode.util.CollectionUtils;
import com.blankj.utilcode.util.StringUtils;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class TabLayoutViewDelegate {
    private final TabLayout tabLayout;
    private final ViewPager2 viewPager2;
    private final FragmentStateAdapter fragmentStateAdapter;
    private final List<String> tabTitles;

    private static List<String> tabRes2Str(int... resId) {
        List<String> tabStrList = new ArrayList<>();
        ArrayUtils.forAllDo(resId, (ArrayUtils.Closure<Integer>) (index, item) -> tabStrList.add(StringUtils.getString(item)));
        return tabStrList;
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentActivity fragmentActivity,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragmentActivity, fragmentList, Arrays.asList(tabTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentActivity fragmentActivity,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragmentActivity, fragmentList, tabRes2Str(tabResTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentActivity fragmentActivity,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull List<String> tabTitles) {
        this(tabLayout, viewPager2, MyFragmentStateAdapter.getInstance(fragmentActivity, fragmentList), tabTitles);
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull Fragment fragment,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragment, fragmentList, Arrays.asList(tabTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull Fragment fragment,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragment, fragmentList, tabRes2Str(tabResTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull Fragment fragment,
                                 @NonNull List<Fragment> fragmentList,
                                 @NonNull List<String> tabTitles) {
        this(tabLayout, viewPager2, MyFragmentStateAdapter.getInstance(fragment, fragmentList), tabTitles);
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentStateAdapter fragmentStateAdapter,
                                 @NonNull String... tabTitles) {
        this(tabLayout, viewPager2, fragmentStateAdapter, Arrays.asList(tabTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentStateAdapter fragmentStateAdapter,
                                 @NonNull int... tabResTitles) {
        this(tabLayout, viewPager2, fragmentStateAdapter, tabRes2Str(tabResTitles));
    }

    public TabLayoutViewDelegate(@NonNull TabLayout tabLayout,
                                 @NonNull ViewPager2 viewPager2,
                                 @NonNull FragmentStateAdapter fragmentStateAdapter,
                                 @NonNull List<String> tabTitles) {
        if (fragmentStateAdapter.getItemCount() != CollectionUtils.size(tabTitles)) {
            throw new IllegalStateException("fragmentList 和 tabTitles 长度不一样");
        }
        this.tabLayout = tabLayout;
        this.viewPager2 = viewPager2;
        this.fragmentStateAdapter = fragmentStateAdapter;
        this.tabTitles = tabTitles;
    }

    public void attach() {
        viewPager2.setAdapter(fragmentStateAdapter);
        new TabLayoutMediator(tabLayout, viewPager2, (tab, position) -> tab.setText(tabTitles.get(position))).attach();
    }

    private static class MyFragmentStateAdapter extends FragmentStateAdapter {
        private List<Fragment> fragmentList;

        public static MyFragmentStateAdapter getInstance(@NonNull FragmentActivity fragmentActivity, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragmentActivity);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public static MyFragmentStateAdapter getInstance(@NonNull Fragment fragment, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragment);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public static MyFragmentStateAdapter getInstance(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, List<Fragment> fragmentList) {
            MyFragmentStateAdapter myFragmentStateAdapter = new MyFragmentStateAdapter(fragmentManager, lifecycle);
            myFragmentStateAdapter.setFragmentList(
                    fragmentList
            );
            return myFragmentStateAdapter;
        }

        public MyFragmentStateAdapter(@NonNull FragmentActivity fragmentActivity) {
            super(fragmentActivity);
        }

        public MyFragmentStateAdapter(@NonNull Fragment fragment) {
            super(fragment);
        }

        public MyFragmentStateAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
            super(fragmentManager, lifecycle);
        }

        public void setFragmentList(List<Fragment> fragmentList) {
            this.fragmentList = fragmentList;
        }

        @NonNull
        @Override
        public Fragment createFragment(int position) {
            return this.fragmentList.get(position);
        }

        @Override
        public int getItemCount() {
            return this.fragmentList.size();
        }
    }
}
